package tagdb.algorithm.tag;

import tagdb.algorithm.graph.Edge;
import tagdb.algorithm.graph.Graph;
import tagdb.fragmentation.IonType;
import tagdb.fragmentation.Masses;
import tagdb.fragmentation.SpectrumPeak;
import tagdb.io.MascotGenericFile;

import java.util.ArrayList;
import java.util.List;

/**
 * This class is used to calculate y- and b-ions of the c-terminal
 * via de novo sequencing.
 * @author Thilo Muth
 *
 */
public class DenovoTagger {

    /**
     * List of spectrum peaks
     */
    private List<SpectrumPeak> peaks;

    /**
     * The peak graph.
     */
    private Graph graph;

    public DenovoTagger(MascotGenericFile mgf) {
        this.peaks = mgf.getPeakList();
        buildGraph();
    }

    /**
     * This method searches for the y-ions.
     */
    public void searchYIons() {
        List<Edge> startEdges = graph.getEdgesForPeak(new SpectrumPeak(0.0, 1.0));
        TagElement y1 = null;
        y1 = checkTrypticIons(startEdges);
        if(graph.getEdgesForPeak(y1.getPeak()) != null) {

        }
    }

    /**
     * Returns the list of tag elements.
     * @return List<TagElement> List of tag elements
     */
    private List<TagElement> searchY2Ions(TagElement y1) {
        List<TagElement> y2candidates = new ArrayList<TagElement>();

        if(graph.getEdgesForPeak(y1.getPeak()) != null) {

        }
        return y2candidates;
    }


    /**
     * This method checks the edges for all possible ions of 20 amino acids.
     * @param edges the edges to check
     * @return the list of tag elements
     */
    private List<TagElement> checkAllIons(List<Edge> edges) {
        List<TagElement> tagElements = new ArrayList<TagElement>();
        return tagElements;
    }

    /**
     * This method checks for tryptic ions / amino acids.
     * @param startEdges List of starting edges.
     * @return TagElement
     */
    private TagElement checkTrypticIons(List<Edge> startEdges){
        TagElement tagElement = null;

        // Iterate the start edges.
        for(Edge e : startEdges) {

            // Check the error.
            double errorR = Math.abs(e.getWeight() - (Masses.R + Masses.C_term));
            double errorK = Math.abs(e.getWeight() - (Masses.K + Masses.C_term ));

            if(errorR < 0.1) {
                tagElement = new TagElement(e, IonType.Y_ION, 1, "R".charAt(0), errorR);
            } else
            if (errorK < 0.1) {
                tagElement =  new TagElement(e, IonType.Y_ION, 1, "K".charAt(0), errorK);
            }
        }
        return tagElement;
    }

    /**
     * Builds the peak graph.
     */
    private void buildGraph() {
        graph = new Graph(peaks);
    }


}
